package icu.lookyousmileface.cas;


import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author starrysky
 * @title: ReferenceUse
 * @projectName Juc_Pro
 * @description: AtomicStampedReference
 * @date 2021/1/308:17 下午
 */
public class ReferenceUse {
    public static void main(String[] args) {
        AtomicStampedReference<Integer> atomicRefe = new AtomicStampedReference<>(1, 1);

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                5,
                Runtime.getRuntime().availableProcessors(),
                5,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );

        try {
            threadPoolExecutor.execute(()->{
                int stamp = atomicRefe.getStamp();
                System.out.println(Thread.currentThread().getName()+"=>"+stamp);

                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                atomicRefe.compareAndSet(1,2,atomicRefe.getStamp(),atomicRefe.getStamp()+1);
                System.out.println(Thread.currentThread().getName()+"=>"+atomicRefe.getStamp());

                System.out.println(atomicRefe.compareAndSet(2, 1, atomicRefe.getStamp(), atomicRefe.getStamp() + 1));
                System.out.println(Thread.currentThread().getName()+"=>"+atomicRefe.getStamp());
            });
            /**
             * 和乐观锁的原理一样
             */
            threadPoolExecutor.execute(()->{
                int stamp = atomicRefe.getStamp();
                System.out.println(Thread.currentThread().getName()+"=>"+stamp);

                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(atomicRefe.compareAndSet(1, 2, stamp, stamp + 1));

                System.out.println(Thread.currentThread().getName()+"=>"+atomicRefe.getStamp());
            });
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        threadPoolExecutor.shutdown();
        }
    }
}
